package com.radiant.main;
/*
 * Copyright 2010-2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ws.rs.core.MediaType;


import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.CreateDomainRequest;
import com.amazonaws.services.simpledb.model.DeleteDomainRequest;
import com.radiant.config.SimpleDBModule;
import com.radiant.data.entity.Child;
import com.radiant.data.entity.Comment;
import com.radiant.data.entity.DevelopmentTrack;
import com.radiant.data.entity.DevelopmentTrack.TrackItem;
import com.radiant.data.entity.DevelopmentTrack.MilestoneType;
import com.radiant.data.entity.DevelopmentTrackDAO;
import com.radiant.data.entity.Month;
import com.radiant.data.entity.Post;
import com.radiant.data.entity.Sex;
import com.radiant.data.entity.User;
import com.radiant.service.ActivityFeedService;
import com.radiant.service.PhotoService;
import com.radiant.service.PostService;
import com.radiant.service.UserService;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataMultiPart;

/**
 * This sample demonstrates how to make basic requests to Amazon SimpleDB using
 * the AWS SDK for Java.
 * <p>
 * <b>Prerequisites:</b> You must have a valid Amazon Web Services developer
 * account, and be signed up to use Amazon SimpleDB. For more information on
 * Amazon SimpleDB, see http://aws.amazon.com/simpledb.
 * <p>
 * <b>Important:</b> Be sure to fill in your AWS access credentials in the
 *                   AwsCredentials.properties file before you try to run this
 *                   sample.
 * http://aws.amazon.com/security-credentials
 */
public class PopulateSampleData {

	private static final String BASE_URL = "http://localhost:8080/webservice";
	
    public static void main(String[] args) throws Exception {
        /*
         * Important: Be sure to fill in your AWS access credentials in the
         *            AwsCredentials.properties file before you try to run this
         *            sample.
         * http://aws.amazon.com/security-credentials
         */
    	ClientConfiguration cc = new ClientConfiguration();
    	cc.setMaxErrorRetry(10);
    	AmazonSimpleDB sdb = new AmazonSimpleDBClient(new PropertiesCredentials(
                PopulateSampleData.class.getResourceAsStream("/AwsCredentials.properties")), cc);

        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(
                PopulateSampleData.class.getResourceAsStream("/AwsCredentials.properties")), cc);

        System.out.println("===========================================");
        System.out.println("Getting Started with Amazon SimpleDB");
        System.out.println("===========================================\n");

        // Create domains
        String[] domains = {"Post", "Comment", "Child", "User", "Profile", 
        		"DevelopmentTrack", "Activity", "Measurement", "Milestone"};

        List<String> existingDomains = sdb.listDomains().getDomainNames();

        for (String domain: domains) {
            //if(!existingDomains.contains(domain)) {
            	System.out.println("Deleting domain called " + domain + ".\n");
            	sdb.deleteDomain(new DeleteDomainRequest(domain));
            	System.out.println("Creating domain called " + domain + ".\n");
            	sdb.createDomain(new CreateDomainRequest(domain));
           // }
        }
      
        List<Bucket> existingBuckets = s3.listBuckets();
        //if (!existingBuckets.contains(new Bucket(PhotoService.BUCKET_NAME))) {
        	System.out.println("Creating bucket " + PhotoService.BUCKET_NAME + "\n");
        	s3.createBucket(PhotoService.BUCKET_NAME);
        //}

        //UserService userService = SimpleDBModule.getInjector().getInstance(UserService.class);
        //PostService postService = SimpleDBModule.getInjector().getInstance(PostService.class);
        //ActivityFeedService activityFeed = SimpleDBModule.getInjector().getInstance(ActivityFeedService.class);
        DevelopmentTrackDAO trackDAO = SimpleDBModule.getInjector().getInstance(DevelopmentTrackDAO.class); 
        
        for (Month month: Month.values()) {
        	DevelopmentTrack dt = new DevelopmentTrack();
        	dt.setChildId(Child.DEFAULT_CHILD_NAME);
        	dt.setMonth(month);
        	dt.setShould(getMilestones(MilestoneType.SHOULD));
        	dt.setMay(getMilestones(MilestoneType.MAY));
        	dt.setProbable(getMilestones(MilestoneType.PROBABLE));
        	dt.setEat(getMilestones(MilestoneType.EAT));
        	dt.setSleep(getMilestones(MilestoneType.SLEEP));
        	trackDAO.save(dt);
        }

        User user1 = createUser("Arun", "arun123");
        String token1 = authenticateUser("Arun", "arun123");
        addChild(token1, "Ari", new Date(), Sex.MALE);

        User user2 = createUser("Tarun", "tarun123");
        String token2 = authenticateUser("Tarun", "tarun123");
        addChild(token2, "Tara", new Date(), Sex.FEMALE);

        User user3 = createUser("Karun", "karun123");
        String token3 = authenticateUser("Karun", "karun123");
        addChild(token3, "Kara", new Date(), Sex.FEMALE);
        addChild(token3, "Karan", new Date(), Sex.MALE);

        addFriend(token1, user2.getUserId());
        addFriend(token1, user3.getUserId());

        InputStream is = getInputStreamFromFile("/logo.gif");
        Post p = createPost(token1, "My first picture", is);
        is.close();

        likePost(token2, p.getPostId());

        likePost(token3, p.getPostId());

        Comment comment = addComment(token3, p.getPostId(), "Nice one!");

        likeComment(token1, comment.getCommentId());

        getTopNPosts(token1, 100);
        getActivityFeed(token1, 100);

        getActivityFeed(token2, 100);

        getActivityFeed(token3, 100);

        getPersonalActivityFeed(token1, 100);

        getPersonalActivityFeed(token2, 100);

        getPersonalActivityFeed(token3, 100);

    }
    
    private static void getPersonalActivityFeed(String token, int count) {
    	  Client c = Client.create();
          
          WebResource r = c.resource(BASE_URL + "/activity/personal/topN")
          		.queryParam("token", token)
          		.queryParam("count", String.valueOf(count));
           
          String response = r
          .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
          .accept(MediaType.APPLICATION_JSON_TYPE)
          .get(String.class);
          
          System.out.println(response);
	}

	private static void getActivityFeed(String token, int count) {
        Client c = Client.create();
        
        WebResource r = c.resource(BASE_URL + "/activity/all/topN")
        		.queryParam("token", token)
        		.queryParam("count", String.valueOf(count));
         
        String response = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .get(String.class);
        
        System.out.println(response);
	}

	private static void getTopNPosts(String token, int count) {
        Client c = Client.create();
        
        WebResource r = c.resource(BASE_URL + "/post/topN")
        		.queryParam("token", token)
        		.queryParam("count", String.valueOf(count));
         
        String response = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .get(String.class);
        
        System.out.println(response);
		
	}

	private static void likeComment(String token, String commentId) {
        Client c = Client.create();
        
        WebResource r = c.resource(BASE_URL + "/post/likeComment")
        		.queryParam("token", token);

        Form userForm = new Form();
        userForm.add("commentId", commentId);

        String response = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(String.class, userForm);
        
        System.out.println(response);
	}

	private static Comment addComment(String token, String postId,
			String message) {
        Client c = Client.create();

        WebResource r = c.resource(BASE_URL + "/post/comment/new")
        		.queryParam("token", token);

        Form userForm = new Form();
        userForm.add("postId", postId);
        userForm.add("message", message);

        Comment comment = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(Comment.class, userForm);
        
        return comment;
	}

	private static void likePost(String token, String postId) {
        Client c = Client.create();
        
        WebResource r = c.resource(BASE_URL + "/post/likePost")
        		.queryParam("token", token);

        Form userForm = new Form();
        userForm.add("postId", postId);

        String response = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(String.class, userForm);
        
        System.out.println(response);
		
	}

	private static User createUser(String userName, String password) {
        Client c = Client.create();
        
        WebResource r = c.resource(BASE_URL + "/user/new");
         
        Form userForm = new Form();
        userForm.add("userName", userName);
        userForm.add("password", password);

        User response = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(User.class, userForm);
        
        return response;
    }

    private static String authenticateUser(String userName, String password) {
        Client c = new Client();
    	WebResource r = c.resource(BASE_URL + "/authentication/authenticateUser");
        
        Form userForm = new Form();
        userForm.add("userName", userName);
        userForm.add("password", password);

        String token = r
        .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(String.class, userForm);
        
        return token;
    }
    
    private static void addChild(String token, String childName, Date dateOfBirth, Sex sex) {
        Client c = new Client();
        WebResource r = c.resource(BASE_URL + "/user/addChild").queryParam("token", token);
        Form userForm = new Form();
        userForm.add("childName", childName);
        userForm.add("dateOfBirth", dateOfBirth);
        userForm.add("sex", sex);

        r.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(userForm);

    }
    
    private static void addFriend(String token, String friendId) {
        Client c = new Client();
        WebResource r = c.resource(BASE_URL + "/user/addFriend").queryParam("token", token);
        Form userForm = new Form();
        userForm.add("friendId", friendId);

        r.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
        .accept(MediaType.APPLICATION_JSON_TYPE)
        .post(userForm);
    }

    private static Post createPost(String token, String message, InputStream inputStream) {
        Client c = new Client();
        WebResource r = c.resource(BASE_URL + "/post/image/new").queryParam("token", token);

        FormDataMultiPart form = new FormDataMultiPart();
        form.bodyPart(new FormDataBodyPart("message", message));

        FormDataBodyPart fdp = new FormDataBodyPart("file",
          inputStream,
          MediaType.APPLICATION_OCTET_STREAM_TYPE);
        form.bodyPart(fdp);

        Post post = r.type(MediaType.MULTIPART_FORM_DATA)
        		.accept(MediaType.APPLICATION_JSON_TYPE)
        		.post(Post.class, form);
        
        return post;
        
    }
    
    private static List<TrackItem> getMilestones(MilestoneType type) {
    	List<TrackItem> milestones = new ArrayList<TrackItem>();
    	TrackItem m = new TrackItem();
    	switch (type) {
    		case SHOULD: 
    			m.setValue("Should do this");
    			break;
    		case EAT:
    			m.setValue("Should eat this");
    			break;
    		case MAY:
    			m.setValue("May do this");
    			break;
    		case PROBABLE: 	
    			m.setValue("Probably do this");
    			break;
    		case SLEEP:
    			m.setValue("Should sleep x...");
    			break;
    	}
    	milestones.add(m);
    	return milestones;
    }
    
    public static InputStream getInputStreamFromFile(String fileName) throws IOException {
        return PopulateSampleData.class.getResourceAsStream(fileName);
    }
}
